package pers.vic.practice;

import jdk.nashorn.internal.ir.IdentNode;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.stream.Collectors;

/**
 * 描述:模拟虚拟存储器中用于页面置换的 LRU算法
 * @author Vic.xu
 * @date 2022-04-01 16:28
 */
public class LruPageReplacementStrategy extends AbstractPageReplacement {

    @Override
    void replace(int n, int[] pagesSequence) {
        printPagesSequence("LRU", n, pagesSequence);
        LinkedHashMap<Integer,Object> map = initLurMap(n);
        int missNumber = 0;
        for (int seq : pagesSequence) {
            System.out.print("访问页号:" + seq + " 访问前：" + getMapDesc(map, n));
            StringBuilder sb = new StringBuilder();
            if (map.containsKey(seq)) {
                sb.append("\t不缺页");
            }else {
                missNumber++;
                sb.append("\t缺页");
                map.put(seq, null);
                sb.append("\t置入 " + seq);
            }
            System.out.print(sb.toString());
            System.out.println(" 访问后：" + getMapDesc(map, n));

        }
        printPageMissRate(missNumber, pagesSequence.length);
    }

    /**
     * 获得map的描述：打印key
     */
    private static String getMapDesc(LinkedHashMap<Integer,Object> map, int n){
        List<String> list = map.keySet().stream().map(String::valueOf).collect(Collectors.toList());
        int size = list.size();
        while (n - size++ > 0) {
            list.add("-");
        }
        return " | " + String.join(" | ", list) + " | ";
    }

    public LinkedHashMap<Integer,Object> initLurMap(int size){
        /**
         * 第三个参数accessOrder，默认false，遍历元素的时候按照插入顺序；如果为true则按照访问顺序
         */
        LinkedHashMap<Integer,Object> map = new LinkedHashMap<Integer,Object>(3, 0.75F, true){

            /**
             * 当map中的元素大于阈值时移除最老的元素
             */
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                boolean removed = size() > size;
                if (removed) {
                    System.out.print("移除元素" + eldest.getKey());
                }
                return size() > size;
            }
        };
        return map;
    }

    public static void main(String[] args) {




    }

}
